﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace OOSync
{
    /// <summary>
    /// 同步对象
    /// </summary>
    public class SyncObj_Server
    {
        public SyncObj_Server(DirtyDataDispatcher dispatcher)
        {
            m_Parent = null;
            m_ownerDirtyDataDispatcher = dispatcher;
            m_Name = ""; 
        }

        public SyncObj_Server(DirtyDataDispatcher dispatcher, SyncObj_Server parent, Dictionary<string, string> KeyValues, string name)
        {
            m_Parent = parent == null ? dispatcher.RootObj : parent;
            m_ownerDirtyDataDispatcher = dispatcher;
            m_Name = name;

            if (KeyValues != null && KeyValues.Count > 0)
                foreach (KeyValuePair<string, string> kv in KeyValues)
                {
                    string attrName = kv.Key;
                    key_values.Add(attrName, kv.Value);
                    dirty_keys.Add(attrName);
                }

            m_Parent._AddChild(this);
            SetChanged();
        }


        public void SetValue(string attrName, string value)
        {
            if (value == null) value = "";//不允许空值

            if (key_values.ContainsKey(attrName))
                key_values[attrName] = value;
            else
                key_values.Add(attrName, value);

            if (!dirty_keys.Contains(attrName)) dirty_keys.Add(attrName);
            SetChanged();
        }

        public void SetValue(string attrName, int value)
        {
            SetValue(attrName, value.ToString());
        }

        public void SetValue(string attrName, uint value)
        {
            SetValue(attrName, value.ToString());
        }

        public void SetValue(string attrName, ulong value)
        {
            SetValue(attrName, value.ToString());
        }

        public void SetValue(string attrName, long value)
        {
            SetValue(attrName, value.ToString());
        }

        public void SetValue(string attrName, float value)
        {
            SetValue(attrName, value.ToString());
        }

        //public string GetValue(string attrName) { return key_values[attrName]; }


        public string Name { get { return m_Name; } }

        public DirtyDataDispatcher OwnerDirtyDataDispatcher { get { return m_ownerDirtyDataDispatcher; } }

        public SyncObj_Server Parent
        {
            get { return m_Parent; }
        }

        public void RemoveChild(SyncObj_Server obj)
        {
            if (!m_Child.Contains(obj)) return;

            m_Child.Remove(obj);

            obj.RemovePath = obj.Parent.Path;//记录删除前的路径
            obj.m_Parent = null;
            obj.SetChanged();
        }

        public void RemoveAllChild()
        {
            var list = new List<SyncObj_Server>();
            foreach (var v in m_Child) list.Add(v);

            for(var i=0;i<list.Count;i++) RemoveChild(list[i]);
        }

        public string Path
        {
            get
            {
                //处理根对象
                if (Parent == null)
                    return (this != OwnerDirtyDataDispatcher.RootObj) ? null : "";

                var p = Parent.Path;
                return p == null ? null : (p == "" ? Name : p + "/" + Name);
            }
        }


        internal JObject Serialize()
        {

            var reDoc = new JObject();

            if (RemovePath == null)
            {
                //写入名称
                reDoc["n"] = Name;
                //变更的
                if (dirty_keys.Count > 0)
                {
                    var modifys = new  JObject();

                    //变更的对象
                    foreach (string curr in dirty_keys) modifys[curr] = key_values[curr];
                    reDoc["m"] = modifys;
                }
            }
            else//对象已经被删除
            {
                //写入名称
                reDoc["n"]= Name;
                reDoc["d"] = "";//被删除标记
            }

            return reDoc;
        }

        internal void CleanDirty()
        {
            dirty_keys.Clear();
        }

        void SetChanged()
        {
            m_ownerDirtyDataDispatcher.SetChanged(this);
        }

        internal void _AddChild(SyncObj_Server obj)
        {
            if (m_Child.Contains(obj)) return;
            m_Child.Add(obj);
        }



        //long id = g_idseed++;

        HashSet<SyncObj_Server> m_Child = new HashSet<SyncObj_Server>();

        Dictionary<string, string> key_values = new Dictionary<string, string>();//键值对
        HashSet<string> dirty_keys = new HashSet<string>();//脏的key 变更对象
        //HashSet<string> dirty_new_child = new HashSet<string>();//新增的子对象
        //HashSet<string> dirty_removed_child = new HashSet<string>();//移除的子对象
        internal SyncObj_Server m_Parent;
        internal string RemovePath = null;
        DirtyDataDispatcher m_ownerDirtyDataDispatcher;
        //bool m_NeedSendTag = true;
        //string m_tag;
        //static long g_idseed = 1;
        string m_Name;//名称
    }
}
